---
title: Steps
description: Using the steps machine in your project.
package: "@zag-js/steps"
---

Steps are used to guide users through a series of steps in a process. It's a
great way to break down a complex process into smaller, more manageable steps.

<Resources pkg="@zag-js/steps" />

<Showcase id="Steps" />

**Features**

- Supports horizontal and vertical orientations
- Support for changing the active step with the keyboard and pointer
- Support for linear and non-linear steps

## Installation

To use the steps machine in your project, run the following command in your
command line:

<CodeSnippet id="steps/installation.mdx" />

## Anatomy

To set up the steps correctly, you'll need to understand its anatomy and how we
name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.

<Anatomy id="steps" />

## Usage

First, import the steps package into your project

```jsx
import * as steps from "@zag-js/steps"
```

The steps package exports two key functions:

- `machine` — The state machine logic for the steps widget.
- `connect` — The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll also need to provide a unique `id` to the `useMachine` hook. This is
> used to ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the
steps machine in your project 🔥

<CodeSnippet id="steps/usage.mdx" />

## Setting the initial step

Set the initial step by passing the `step` property to the machine context.

> The value of the `step` property is zero-based index.

```jsx {2}
const service = useMachine(steps.machine, {
  defaultStep: 1,
})
```

## Listening for step change

When the active step changes, the machine will invoke the `onStepChange` event

```jsx {2-4}
const service = useMachine(steps.machine, {
  onStepChange(details) {
    // details => { step: number }
    console.log(`Step changed to ${details.step}`)
  },
})
```

## Listening for steps completion

When all steps are completed, the machine will invoke the `onStepComplete` event

```jsx {2-4}
const service = useMachine(steps.machine, {
  onStepComplete() {
    console.log("All steps are complete")
  },
})
```

## Enforcing linear steps

To enforce linear steps, you can set the `linear` prop to `true` when creating
the steps machine. This will prevent users from skipping steps.

```jsx {2}
const service = useMachine(steps.machine, {
  linear: true,
})
```

## Changing the orientation

The steps machine supports both horizontal and vertical orientations. You can
set the `orientation` prop to `horizontal` or `vertical` to change the
orientation of the steps.

```jsx {2}
const service = useMachine(steps.machine, {
  orientation: "vertical",
})
```

## Styling guide

Earlier, we mentioned that each steps part has a `data-part` attribute added to
them to select and style them in the DOM.

```css
[data-scope="steps"][data-part="root"] {
  /* styles for the root part */
}

[data-scope="steps"][data-part="root"][data-orientation="horizontal|vertical"] {
  /* styles for the root part based on orientation */
}

[data-scope="steps"][data-part="list"] {
  /* styles for the list part */
}

[data-scope="steps"][data-part="list"][data-orientation="horizontal|vertical"] {
  /* styles for the list part based on orientation */
}

[data-scope="steps"][data-part="separator"] {
  /* styles for the separator part */
}

[data-scope="steps"][data-part="separator"][data-orientation="horizontal|vertical"] {
  /* styles for the separator part based on orientation */
}
```

### Current step

To style the current step, you can use the `data-current` attribute.

```css
[data-scope="steps"][data-part="item"][data-current] {
  /* item styles for the current step */
}

[data-scope="steps"][data-part="separator"][data-current] {
  /* separator styles for the current step */
}
```

### Completed step

To style the completed step, you can use the `data-complete` attribute.

```css
[data-scope="steps"][data-part="item"][data-complete] {
  /* item styles for the completed step */
}

[data-scope="steps"][data-part="separator"][data-complete] {
  /* separator styles for the completed step */
}
```

### Incomplete step

To style the incomplete step, you can use the `data-incomplete` attribute.

```css
[data-scope="steps"][data-part="item"][data-incomplete] {
  /* item styles for the incomplete step */
}

[data-scope="steps"][data-part="separator"][data-incomplete] {
  /* separator styles for the incomplete step */
}
```

## Methods and Properties

### Machine Context

The steps machine exposes the following context properties:

<ContextTable name="steps" />

### Machine API

The steps `api` exposes the following methods:

<ApiTable name="steps" />

### Data Attributes

<DataAttrTable name="steps" />

### CSS Variables

<CssVarTable name="steps" />
